<template>
  <div>
    <el-dialog v-if="enable" :visible.sync="enable" :title="`${site} : ${actionName}`" :close-on-click-modal="false">
      <div id="apache-virtualhost-deplay-terminal"></div>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="'wait' == status" type="primary" @click="actionStart">开始</el-button>
        <el-button v-if="'success' == status" @click="actionClose">关闭</el-button>
        <el-button v-if="'failed' == status" @click="actionStart">重新执行</el-button>
        <el-button v-if="'failed' == status" @click="actionClose">关闭</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { Terminal } from 'xterm'
require('xterm/css/xterm.css');
import { FitAddon } from "xterm-addon-fit";
import Common from '../../utils/Common.js';
export default {
    name : 'DialogVirtualHostDeploy',
    data() {
        return {
            enable : false,
            site : null,
            action : null,
            status : 'wait',
        };
    },
    computed : {
        actionName () {
            return {'update':'更新','rollback':'回滚'}[this.action];
        },
    },
    methods : {
        // 开始部署
        async open( site, action ) {
            this.site = site;
            this.action = action;
            this.enable = true;
            this.status = 'wait';
            
            await Common.msleep(100);
            this.terminal = new Terminal({
                cursorBlink: true,
                cursorStyle: "underline",
                scrollback: 100,
            });
            const fitAddon = new FitAddon();
            this.terminal.loadAddon(fitAddon);
            this.terminal.open(document.getElementById('apache-virtualhost-deplay-terminal'));
            fitAddon.fit();

            
        },

        // 关闭对话框
        async actionClose() {
            this.enable = false;
            this.terminal.dispose();
        },

        // 开始执行
        async actionStart() {
            if ( 'update' == this.action ) {
                this.startUpdate();
            } else {
                this.startRollback();
            }
        },
        
        // 更新
        async startUpdate() {
            let server = this.$store.getters.serverCurrent;
            let updateScriptPath = server.getPath(`websites/${this.site}/deploy-update.sh`);
            if ( ! await Common.isFileExists(updateScriptPath) ) {
                this.$message.error('部署脚本不存在，无法执行');
                this.enable = false;
                return;
            }

            let updateScriptContent = await Common.fileGetContent(updateScriptPath);
            let tmpFilePath = await server.exec('mktemp');
            tmpFilePath = tmpFilePath.trim();
            await server.filePutContent(tmpFilePath, updateScriptContent);
            await server.exec(`chmod u+x ${tmpFilePath}`);
            await this.executeScript(tmpFilePath);
            await server.exec(`rm -f ${tmpFilePath}`);
        },

        // 回滚
        async startRollback() {
            let server = this.$store.getters.serverCurrent;
            let rollbackScriptPath = server.getPath(`websites/${this.site}/deploy-rollback.sh`);
            if ( ! await Common.isFileExists(rollbackScriptPath) ) {
                this.$message.error('部署脚本不存在，无法执行');
                this.enable = false;
                return;
            }

            let rollbackScriptContent = await Common.fileGetContent(rollbackScriptPath);
            let tmpFilePath = await server.exec('mktemp');
            tmpFilePath = tmpFilePath.trim();
            await server.filePutContent(tmpFilePath, rollbackScriptContent);
            await server.exec(`chmod u+x ${tmpFilePath}`);
            await this.executeScript(tmpFilePath);
            await server.exec(`rm -f ${tmpFilePath}`);
        },

        // 执行脚本
        executeScript( path ) {
            let $this = this;
            let server = this.$store.getters.serverCurrent;
            return new Promise(async ( resolve, reject ) => {
                let stream = await server.exec4Stream(path);
                stream.on("data", (data) => {
                    $this.terminal.write(data.toString());
                });
                stream.on('exit', function(code, signal) {
                    if ( 0 != code ) {
                        $this.status = 'failed';
                        $this.$message.error('部署失败');
                    } else {
                        $this.status = 'success';
                    }
                    resolve();
                });
            });
        },
    },
}
</script>